package com.tarena.platform.email;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.Message;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 邮件发送帮助类
 * 
 * @author tarena
 *
 */
public class EmailSendUtil {
	private static Logger log = LoggerFactory.getLogger(PropertiesReader.class);

	/**
	 * 发送邮件
	 * @param receiverAddress
	 * @param subject
	 * @param body
	 * @throws Exception
	 */
	public static void sendEmail(String receiverAddress, String subject, String body) throws Exception {
		 sendEmail(Arrays.asList(receiverAddress), null, EmailConfig.apiUser, subject, body, EmailConfig.apiUser);
	}

	/**
	 * 发送邮件
	 * @param receiverAddress
	 * @param subject
	 * @param body
	 * @param displayName
	 * @throws Exception
	 */
	public static void sendEmail(String receiverAddress, String subject, String body, String displayName) throws Exception {
		 sendEmail(Arrays.asList(receiverAddress), null, EmailConfig.apiUser, subject, body, displayName);
	}

	/**
	 * 发送邮件
	 * @param receiverAddress
	 * @param copyForAddres
	 * @param subject
	 * @param body
	 * @param displayName
	 * @throws Exception
	 */
	public static void sendEmail(String receiverAddress, String copyForAddres, String subject, String body, String displayName) throws Exception {
		 sendEmail(Arrays.asList(receiverAddress), Arrays.asList(copyForAddres), EmailConfig.apiUser, subject, body, displayName);
	}

	/**
	 * 
	 * @param receiverAddress
	 * @param copyForAddress
	 * @param subject
	 * @param body
	 * @param displayName
	 * @throws Exception
	 */
	public static void sendEmail(String receiverAddress, List<String> copyForAddress, String subject, String body, String displayName) throws Exception {
		 sendEmail(Arrays.asList(receiverAddress), copyForAddress, EmailConfig.apiUser, subject, body, displayName);
	}
	/**
	 * 
	 * @param receiverAddress 收件箱
	 * @param copyForAddress 抄送
	 * @param formAddress 发件箱
	 * @param subject 主体
	 * @param body 内容
	 * @param displayName 展示名称
	 * @throws Exception
	 */
	public static void sendEmail(List<String> receiverAddress, List<String> copyForAddress, String formAddress, String subject, String body, String displayName) throws Exception {
		 sendEmailOper(receiverAddress, copyForAddress, formAddress, subject, body, displayName);
	}

	private static MimeMessage createMimeMessage(String subject, String body) throws Exception {
		MimeMessage msg = new MimeMessage(EmailConfig.getMailSession());
		msg.setSubject(subject, "UTF-8");
		msg.setContent(body, "text/html; charset=UTF-8");
		msg.setSentDate(new Date());
		return msg;
	}

	/**
	 * 发送邮件
	 * 
	 * @param receiverAddress 收信人地址
	 * @param copyForAddress  抄送人地址
	 * @param subject         主题
	 * @param body            内容
	 * @param displayName     发送者显示名称 EmailConfig.apiUser
	 * @throws Exception
	 */
	private static void sendEmailOper(List<String> receiverAddress, List<String> copyForAddress, String formAddress, String subject, String body, String displayName) throws Exception {
		log.info("初始化配置信息");
		// 设置消息的各部分
		if (subject == null || subject.trim().isEmpty()) {
			log.error("主题为空");
			throw new Exception("主题为空");
		}
		if (body == null || body.trim().isEmpty()) {
			log.error("内容为空");
			throw new Exception("内容为空");
		}
		MimeMessage msg = createMimeMessage(subject, body);
		// 设置发件人地址
		InternetAddress fromAddress = new InternetAddress(formAddress, displayName, "UTF-8");
		msg.setFrom(fromAddress);
		// 收件人为空就是异常
		InternetAddress[] toAddress = toAddress(receiverAddress);
		log.info("添加收件人地址");
		msg.setRecipients(Message.RecipientType.TO, toAddress);

		// 抄送邮箱地址,抄送人允许为空
		InternetAddress[] copyAddress = copyAddress(copyForAddress);
		if (copyAddress != null) {
			log.info("添加抄送人地址");
			msg.setRecipients(Message.RecipientType.CC, copyAddress);
		}
		// 保存改变
		msg.saveChanges();
		Transport transport = EmailConfig.getTransportInstance();
		transport.connect();
		log.info("开始发送邮件");
		long start = System.currentTimeMillis();
		transport.sendMessage(msg, msg.getAllRecipients());
		long end = System.currentTimeMillis();
		log.info("邮件发送成功，耗时：{}毫秒", (end - start));
		transport.close();
	}

	/**
	 * 验证获取 发送地址
	 * 
	 * @throws Exception
	 **/
	public static InternetAddress[] toAddress(List<String> receiverAddress) throws Exception {
		if (CollectionUtils.isEmpty(receiverAddress)) {
			throw new Exception("请输入收件人邮箱地址");
		}
		InternetAddress[] toAddress = new InternetAddress[receiverAddress.size()];
		for (int i = 0; i < receiverAddress.size(); i++) {
			if (!isEmail(receiverAddress.get(i))) {
				log.error("邮箱不正确！");
				throw new Exception("抄送邮箱格式不正确");
			}
			toAddress[i] = new InternetAddress(receiverAddress.get(i));
		}
		return toAddress;
	}

	/**
	 * 验证获取 抄送地址
	 * 
	 * @throws Exception
	 **/
	public static InternetAddress[] copyAddress(List<String> copyForAddress) throws Exception {
		if (CollectionUtils.isEmpty(copyForAddress)) {
			return null;
		}
		InternetAddress[] copyAddress = new InternetAddress[copyForAddress.size()];
		for (int i = 0; i < copyForAddress.size(); i++) {
			if (!isEmail(copyForAddress.get(i))) {
				log.error("邮箱不正确！");
				throw new Exception("抄送邮箱格式不正确");
			}
			copyAddress[i] = new InternetAddress(copyForAddress.get(i));
		}
		return copyAddress;
	}

	/**
	 * 邮箱验证
	 * 
	 * @param str
	 * @return 验证通过返回true
	 */
	private static boolean isEmail(String str) {
		Pattern p = null;
		Matcher m = null;
		boolean b = false;
		p = Pattern.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
		m = p.matcher(str);
		b = m.matches();
		return b;
	}
}
